module injector (
	input clk,
	input reset_n,
	input [2 : 0] apply,
	input [2 : 0] inject,
	input [2 : 0] mode,
	input [2 : 0] original,
	output [2 : 0] tampered
);

// mode = 0 simulates xor fault (inverted output);
// mode = 1 simulates stuck at valueof(inject) fault
reg [2 : 0] saved_mode;

// inject = 0 simulates injection of 0 according to mode
// inject = 1 simulates injection of 1 according to mode
reg [2 : 0] saved_inject;

assign tampered[0] = saved_mode[0] ? (saved_inject[0] & original[0]) : (saved_inject[0] ^ original[0]);
assign tampered[1] = saved_mode[1] ? (saved_inject[1] & original[1]) : (saved_inject[1] ^ original[1]);
assign tampered[2] = saved_mode[2] ? (saved_inject[2] & original[2]) : (saved_inject[2] ^ original[2]);

always @(posedge clk) begin
	if (reset_n == 1'b0) begin
		saved_mode <= 0;
		saved_inject <= 0;
	end else begin
		saved_mode <= apply & mode;
		saved_inject <= apply & inject;
	end
end

endmodule